package com.itheima.ydd.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.ydd.common.ResultData;
import com.itheima.ydd.dto.ConfigDto_Children;
import com.itheima.ydd.dto.ConfigDto_List;
import com.itheima.ydd.dto.ConfigDto_allData;
import com.itheima.ydd.entity.Config;
import com.itheima.ydd.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yan.zhou
 * @date 2022/2/16
 */
@Slf4j
@RestController
@RequestMapping("sys_config")
public class ConfigController {
    /**
     * update   POST    已测
     * all      GET     已测
     */
    @Autowired
    private ConfigService configService;

    //@GetMapping("/all")
    public ResultData all() {

        Map<String, Object> map = configService.all();
        return ResultData.ok("", map);

    }

    /*
    data
        -lsit
        -allData
            -list<ConfigDto_allData>
        -configForm
            -map集合
        -configRules
            --map集合


     */


    @GetMapping("/all")
    public ResultData all1() {

        HashMap<String, Object> data = new HashMap<>();

        List<Config> configList = configService.list();

        //先存allData;
        List<ConfigDto_allData> allData = configList.stream().map(s -> {
            ConfigDto_allData configDto_allData = new ConfigDto_allData();
            BeanUtils.copyProperties(s, configDto_allData);
            return configDto_allData;
        }).collect(Collectors.toList());
        data.put("allData",allData);

        //再存configForm;
        Map<String, String> configForm = configList.stream().collect(Collectors.toMap(Config::getAttr_key, Config::getAttr_value));
        data.put("configForm",configForm);

        //再存configRules;
        Map<String, String> configRules = configList.stream().filter(s->{
            if (StringUtils.isNotEmpty(s.getValidator())){
                return true;
            }
            return false;
        }).collect(Collectors.toMap(Config::getAttr_key, Config::getValidator));
        data.put("configRules",configRules);


        //获取所有的tab_value类型  base system custom
        Set<String> tabValue = configList.stream().map(s -> {
            String tab_value = s.getTab_value();
            return tab_value;
        }).collect(Collectors.toSet());


        //获取不同tableValue下的group_value;
        //可以优化成stream流节省内存,但是写不来,得到key tableValue  value 是对应list的Map集合
        HashMap<String, List<String>> tableValue_groupValue = new HashMap<>();

        HashMap<String, List<Config>> groupValue_Config = new HashMap<>();

        for (String tableValue : tabValue) {
            LambdaQueryWrapper<Config> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
            objectLambdaQueryWrapper.select(Config::getGroup_value).eq(Config::getTab_value,tableValue).groupBy(Config::getGroup_value);
            List<Config> list = configService.list(objectLambdaQueryWrapper);

            ArrayList<String> groupValue = new ArrayList<>();
            list.forEach(s->{
                groupValue.add(s.getGroup_value());
            });
            tableValue_groupValue.put(tableValue,groupValue);

            //list中包含每个base base system custom下级分类
            //可以直接查找下级分类,然后创建新的map集合进行装填
            for (Config config : list) {
                String group_value = config.getGroup_value();
                LambdaQueryWrapper<Config> configLambdaQueryWrapper = new LambdaQueryWrapper<>();
                configLambdaQueryWrapper.eq(Config::getGroup_value,group_value);
                List<Config> groupValueList = configService.list(configLambdaQueryWrapper);
                groupValue_Config.put(group_value,groupValueList);
            }
        }


        //开始往ConfigDto_List 回填数据了;
        //首先回填第name key 属性
        List<ConfigDto_List> configDto_List = tabValue.stream().map(s -> {
            ConfigDto_List configDto_list = new ConfigDto_List();
            configDto_list.setKey(s);
            switch (s) {
                case "base":
                    configDto_list.setName("基础配置");
                    break;
                case "system":
                    configDto_list.setName("系统设置");
                    break;
                case "custom":
                    configDto_list.setName("其他设置");
                    break;
            }
            return configDto_list;

        }).collect(Collectors.toList());


        //最后的封装
        ArrayList<ConfigDto_Children> children = new ArrayList<>();


        //再次回填children属性
        for (ConfigDto_List configDto_list : configDto_List) {

            String tab_value = configDto_list.getKey();
            List<String> configs = tableValue_groupValue.get(tab_value);


            for (String config : configs) {

                List<Config> configs1 = groupValue_Config.get(config);
                ConfigDto_Children configDto_children = new ConfigDto_Children();
                configDto_children.setName(config);
                configDto_children.setData(configs1);
                children.add(configDto_children);
            }
        }

        //最后封装
        for (ConfigDto_List configDto_list : configDto_List) {
            ArrayList<ConfigDto_Children> configDto_children = new ArrayList<>();
            String key = configDto_list.getKey();
            //拿到分级的
            List<String> strings = tableValue_groupValue.get(key);

            for (ConfigDto_Children child : children) {

                String name = child.getName();
                if (strings.toString().contains(name)){
                    configDto_children.add(child);
                }
            }
            configDto_list.setChildren(configDto_children);

        }


        data.put("list",configDto_List);



        return ResultData.ok("",data);
    }



}